#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
软件启动器模块 - 负责启动软件进程
遵循单一职责原则，专门处理软件启动功能

Copyright (c) 2025 RAYA-MAX
Quick-Start is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan
PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""

import os
import subprocess
import sys
from typing import List, Dict, Any, Tuple
import threading
import time


class SoftwareLauncher:
    """软件启动器类 - 处理软件的启动操作"""
    
    def __init__(self):
        """初始化启动器"""
        self.launch_history = []  # 启动历史记录
    
    def launch_software(self, software_path: str, software_name: str = "") -> Tuple[bool, str]:
        """
        启动单个软件
        
        Args:
            software_path: 软件路径
            software_name: 软件名称（用于日志）
            
        Returns:
            (是否成功, 错误信息)
        """
        if not software_path:
            return False, "软件路径为空"
        
        if not os.path.exists(software_path):
            return False, f"软件路径不存在: {software_path}"
        
        try:
            # 根据操作系统选择启动方式
            if sys.platform.startswith('win'):
                # Windows系统
                subprocess.Popen([software_path], shell=True)
            elif sys.platform.startswith('darwin'):
                # macOS系统
                subprocess.Popen(['open', software_path])
            else:
                # Linux系统
                subprocess.Popen([software_path])
            
            # 记录启动历史
            self.launch_history.append({
                'name': software_name or os.path.basename(software_path),
                'path': software_path,
                'timestamp': time.time(),
                'status': 'success'
            })
            
            return True, "启动成功"
            
        except Exception as e:
            error_msg = f"启动失败: {str(e)}"
            
            # 记录失败历史
            self.launch_history.append({
                'name': software_name or os.path.basename(software_path),
                'path': software_path,
                'timestamp': time.time(),
                'status': 'failed',
                'error': error_msg
            })
            
            return False, error_msg
    
    def launch_software_list(self, software_list: List[Dict[str, str]], 
                           delay_seconds: float = 1.0) -> List[Tuple[str, bool, str]]:
        """
        批量启动软件列表
        
        Args:
            software_list: 软件信息列表，每个元素包含name, path, description
            delay_seconds: 启动间隔时间（秒）
            
        Returns:
            启动结果列表，每个元素为(软件名称, 是否成功, 错误信息)
        """
        results = []
        
        for software in software_list:
            name = software.get('name', '未知软件')
            path = software.get('path', '')
            
            success, message = self.launch_software(path, name)
            results.append((name, success, message))
            
            # 如果不是最后一个软件，等待指定时间
            if software != software_list[-1] and delay_seconds > 0:
                time.sleep(delay_seconds)
        
        return results
    
    def launch_software_list_async(self, software_list: List[Dict[str, str]], 
                                 delay_seconds: float = 1.0,
                                 callback=None) -> None:
        """
        异步批量启动软件列表
        
        Args:
            software_list: 软件信息列表
            delay_seconds: 启动间隔时间（秒）
            callback: 完成后的回调函数，接收结果列表作为参数
        """
        def launch_thread():
            results = self.launch_software_list(software_list, delay_seconds)
            if callback:
                callback(results)
        
        thread = threading.Thread(target=launch_thread, daemon=True)
        thread.start()
    
    def validate_software_path(self, software_path: str) -> Tuple[bool, str]:
        """
        验证软件路径是否有效
        
        Args:
            software_path: 软件路径
            
        Returns:
            (是否有效, 验证信息)
        """
        if not software_path:
            return False, "路径为空"
        
        if not os.path.exists(software_path):
            return False, "文件不存在"
        
        if not os.path.isfile(software_path):
            return False, "不是有效的文件"
        
        # 检查文件扩展名（Windows）
        if sys.platform.startswith('win'):
            valid_extensions = ['.exe', '.bat', '.cmd', '.com', '.msi']
            file_ext = os.path.splitext(software_path)[1].lower()
            if file_ext not in valid_extensions:
                return False, f"不支持的文件类型: {file_ext}"
        
        return True, "路径有效"
    
    def get_launch_history(self, limit: int = 10) -> List[Dict[str, Any]]:
        """
        获取启动历史记录
        
        Args:
            limit: 返回记录数量限制
            
        Returns:
            启动历史记录列表
        """
        return self.launch_history[-limit:] if limit > 0 else self.launch_history
    
    def clear_launch_history(self) -> None:
        """清空启动历史记录"""
        self.launch_history.clear()
    
    def get_software_info(self, software_path: str) -> Dict[str, str]:
        """
        获取软件基本信息
        
        Args:
            software_path: 软件路径
            
        Returns:
            软件信息字典
        """
        info = {
            'name': '',
            'path': software_path,
            'exists': False,
            'size': 0,
            'modified_time': ''
        }
        
        if os.path.exists(software_path):
            info['exists'] = True
            info['name'] = os.path.basename(software_path)
            
            try:
                stat_info = os.stat(software_path)
                info['size'] = stat_info.st_size
                info['modified_time'] = time.ctime(stat_info.st_mtime)
            except OSError:
                pass
        
        return info


class LaunchResult:
    """启动结果类 - 封装启动操作的结果"""
    
    def __init__(self, software_name: str, success: bool, message: str):
        """
        初始化启动结果
        
        Args:
            software_name: 软件名称
            success: 是否成功
            message: 结果信息
        """
        self.software_name = software_name
        self.success = success
        self.message = message
        self.timestamp = time.time()
    
    def __str__(self) -> str:
        """返回结果的字符串表示"""
        status = "成功" if self.success else "失败"
        return f"{self.software_name}: {status} - {self.message}"
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'software_name': self.software_name,
            'success': self.success,
            'message': self.message,
            'timestamp': self.timestamp
        }
